package com.youlu.campus.service.commission;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.google.common.collect.Lists;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.FileExportTask;
import com.youlu.campus.entity.commission.DistributorChannelSharingCommissionDetail;
import com.youlu.campus.entity.commission.DistributorCommission;
import com.youlu.campus.entity.commission.SharingCommissionDetail;
import com.youlu.campus.entity.commission.dto.DistributorCommissionOrderExportDTO;
import com.youlu.campus.entity.commission.dto.ExportDistributorChannelSharingCommissionDTO;
import com.youlu.campus.entity.commission.dto.SharingCommissionDetailQueryDTO;
import com.youlu.campus.entity.enums.SharingProfitOrderTypeEnum;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.file.FileExportTaskService;
import com.youlu.campus.service.file.FileService;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SharingCommissionDetailService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private FileExportTaskService fileExportTaskService;

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private DistributorChannelSharingCommissionService distributorChannelSharingCommissionService;

    @Autowired
    private FileService fileService;


    public void exportCommissionDetail(SharingCommissionDetailQueryDTO dto){
        String optUserName = dto.getOptUserName();
        log.info("【个人分销订单导出】start 导出 optUserName:{}", optUserName);
        Integer pageNo = 1;
        Integer pageSize = 2000;
        Boolean createFileTask = Boolean.FALSE;
        List<SharingCommissionDetail> exportDistributorSharingCommissionOrderList = null;
        List<DistributorCommissionOrderExportDTO> exportResult = Lists.newLinkedList();
        String fileExportTaskId = "";
        String fileName = "";
        while (true){
            dto.setPageNo(pageNo);
            dto.setPageSize(pageSize);
            log.info("【个人分销订单导出】查询第几页 page:{} 导出 optUserName:{}",pageNo, optUserName);
            Page<SharingCommissionDetail> pageSharingCommissionDetailList = this.list(dto);
            exportDistributorSharingCommissionOrderList = pageSharingCommissionDetailList.getContent();
            if (CollectionUtils.isEmpty(exportDistributorSharingCommissionOrderList)) {
                log.info("【个人分销订单导出】end 导出 optUserName:{}", optUserName);
                break;
            }
            if (!createFileTask) {
                log.info("【个人分销订单导出】 创建文件导出任务 optUserName:{}", optUserName);
                FileExportTask fileExportTask = new FileExportTask();
                fileExportTask.setToken(optUserName);
                fileExportTask.setBizType("distributor-commission-order");
                fileExportTask.setStatus(0);
                fileExportTask.setOptUser(optUserName);
                fileExportTask.setOptUserId(dto.getOptUserId());
                fileName = "个人分销订单明细-" + System.currentTimeMillis() + ".xlsx";
                fileExportTask.setFileName(fileName);
                fileExportTask.setNum((int) pageSharingCommissionDetailList.getTotalElements());
                fileExportTask.setDesc("个人分销订单明细");
                fileExportTaskId = fileExportTaskService.create(fileExportTask);
                createFileTask = Boolean.TRUE;
            }
            //纸质证书
            List<ExportDistributorChannelSharingCommissionDTO> exportChannelResult = Lists.newLinkedList();
            List<SharingCommissionDetail> paperOrderList = exportDistributorSharingCommissionOrderList.stream().filter(order -> SharingProfitOrderTypeEnum.PAPER_CA_ORDER.equals(order.getSharingProfitOrderType())).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(paperOrderList)){
                List<DistributorChannelSharingCommissionDetail> paperOrderDistributorChannelList = mapperFacade.mapAsList(paperOrderList, DistributorChannelSharingCommissionDetail.class);
                distributorChannelSharingCommissionService.exportPaperCa(paperOrderDistributorChannelList,exportChannelResult);
                paperOrderDistributorChannelList.clear();
            }
            //电子证书
            List<SharingCommissionDetail> digitalCaOderList = exportDistributorSharingCommissionOrderList.stream().filter(order -> SharingProfitOrderTypeEnum.DIGITAL_CA_ORDER.equals(order.getSharingProfitOrderType())).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(digitalCaOderList)){
                List<DistributorChannelSharingCommissionDetail> digitalCaOderCommissionList = mapperFacade.mapAsList(exportDistributorSharingCommissionOrderList, DistributorChannelSharingCommissionDetail.class);
                distributorChannelSharingCommissionService.exportDigitaCa(digitalCaOderCommissionList,exportChannelResult);
                digitalCaOderCommissionList.clear();
            }
            //其他信息分拥订单
            List<SharingCommissionDetail> otherOrderDistributorList = exportDistributorSharingCommissionOrderList.stream().filter(order -> !SharingProfitOrderTypeEnum.PAPER_CA_ORDER.equals(order.getSharingProfitOrderType()) || !SharingProfitOrderTypeEnum.DIGITAL_CA_ORDER.equals(order.getSharingProfitOrderType())).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(otherOrderDistributorList)){
                List<DistributorChannelSharingCommissionDetail>otherOrderDistributorCommissionList = mapperFacade.mapAsList(otherOrderDistributorList, DistributorChannelSharingCommissionDetail.class);
                distributorChannelSharingCommissionService.exportDistributorChannelCommissionDetail(otherOrderDistributorCommissionList,exportChannelResult);
                otherOrderDistributorCommissionList.clear();
            }
            exportResult = mapperFacade.mapAsList(exportChannelResult,DistributorCommissionOrderExportDTO.class);
            List<SharingCommissionDetail> finalExportDistributorSharingCommissionOrderList =
                    exportDistributorSharingCommissionOrderList;
            exportResult.forEach(export->{
                SharingCommissionDetail sharingCommissionDetail =
                        finalExportDistributorSharingCommissionOrderList.stream().filter(sharingCommissionOrder -> sharingCommissionOrder.getOrderNo().equals(export.getOrderNo())).findFirst().orElse(null);
                if(Objects.nonNull(sharingCommissionDetail)){
                    DistributorCommission distributorCommission = sharingCommissionDetail.getDistributorCommission();
                    export.setDistributorName(distributorCommission.getName());
                    export.setDistributorMobile(distributorCommission.getMobile());
                    export.setDistributorOpenId(distributorCommission.getOpenId());
                }
            });
            pageNo++;
        }
        if(CollectionUtils.isEmpty(exportResult)){
            log.info("【个人分销订单导出】end 导出  未找到数据 optUserName:{}", optUserName);
            return;
        }
        ExcelWriter excelWriter = null;
        String file = "/data/app/file/" + fileName;
        try {
            excelWriter = EasyExcel.write(file, DistributorCommissionOrderExportDTO.class).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(1, "渠道分销订单明细表").build();
            excelWriter.write(exportResult, writeSheet);
        }catch (Exception e){
            log.info("【个人分销订单导出】end 导出 错误 optUserName:{}", optUserName,e);
            return;
        }finally {
            if (Objects.nonNull(excelWriter)) {
                excelWriter.finish();
            }
            exportResult.clear();
        }
        File newFile = new File(file);
        if (!newFile.exists()) {
            log.error("找不到个人分销订单明细表文件");
            return;
        }
        InputStream in = null;
        try {
            in = new FileInputStream(newFile);
            String url = fileService.uploadFile(in, fileName);
            Query queryTask = new Query().addCriteria(Criteria.where("id").is(fileExportTaskId));
            Update update = new Update();
            update.set("status", 1);
            update.set("url", url);
            update.set("updatedTime", new Date());
            mongoTemplate.updateFirst(queryTask, update, FileExportTask.class);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            log.error("导出个人分销订单明细表 error", e);
            return;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导出个人分销订单明细表 error", e);
            return;
        } finally {
            if (Objects.nonNull(in)) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        log.info("【个人分销订单导出】end 导出 optUserName:{}", optUserName);
    }



    public Page<SharingCommissionDetail> list(SharingCommissionDetailQueryDTO dto) {
        Integer sharingCommissionStatus = dto.getSharingCommissionStatus();
        Integer pageNo = dto.getPageNo();
        Integer pageSize = dto.getPageSize();
        Query query = new Query();
        if(StringUtils.isNotBlank(dto.getUserId())){
            query.addCriteria(Criteria.where("distributorCommission.userId").is(dto.getUserId()));
        }
        if(Objects.nonNull(sharingCommissionStatus)){
            query.addCriteria(Criteria.where("sharingCommissionStatus").is(sharingCommissionStatus));
        }
        String orderNo = dto.getOrderNo();
        if(StringUtils.isNotBlank(orderNo)){
            query.addCriteria(Criteria.where("orderNo").is(orderNo));
        }
        String openId = dto.getOpenId();
        if(StringUtils.isNotBlank(openId)){
            query.addCriteria(Criteria.where("distributorCommission.openId").is(openId));
        }
        String mobile = dto.getMobile();
        if(StringUtils.isNotBlank(mobile)){
            query.addCriteria(Criteria.where("distributorCommission.mobile").is(mobile));
        }
        Date startPayTime = dto.getStartPayTime();
        Date endPayTime = dto.getEndPayTime();
        if(Objects.nonNull(startPayTime)&&Objects.nonNull(endPayTime)){
            query.addCriteria(Criteria.where("payTime").gte(startPayTime).lte(endPayTime));
        }
        PageRequest pageRequest = PageRequest.of(pageNo - 1, pageSize);
        long count = this.mongoTemplate.count(query, SharingCommissionDetail.class);
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> count);
        }
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<SharingCommissionDetail> commissionDetailList = this.mongoTemplate.find(query.with(pageRequest),
                SharingCommissionDetail.class);
        commissionDetailList.stream().forEach(sharingCommissionDetail -> {
            ActivityInfo activityInfo = activityService.findOne(sharingCommissionDetail.getActivityId());
            if (Objects.nonNull(activityInfo)) {
                sharingCommissionDetail.setActivityName(activityInfo.getName());
            }
        });
        return PageableExecutionUtils.getPage(commissionDetailList, pageRequest, () -> count);
    }


}
